home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / Libraries / BSDSoundLib 1.0.3 / BSDSoundLib.cp next >
Encoding:
Text File  |  1997-08-03  |  7.1 KB  |  326 lines  |  [TEXT/CWIE]

  1. /*
  2.      File:        BSDSoundLib.c
  3.  
  4.      Contains:    Sound Routines.
  5.  
  6.      Version:    Technology:    Torture Chamber v1.0
  7.                  Package:    BSDSoundLib v1.0.3
  8.  
  9.      Copyright:    Â© 1997, BuggySoft™ Development.
  10.                  By Scott Dunbar
  11. */
  12.  
  13. #ifndef __BSDSOUNDLIB_
  14. #include "BSDSoundLib.h"
  15. #endif
  16.  
  17. #define volume(lvol, rvol) (rvol << 16L | lvol)
  18.  
  19. short            numChannels = 0, curSndLoc;
  20. Boolean            sndChanActive[kMaxSndChans], loopingActive;
  21. SndChannelPtr    sndChan[kMaxSndChans], loopingSndChan;
  22. SndCallBackUPP    soundCallBackUPP, loopingCallBackUPP;
  23.  
  24. static SoundHeaderPtr GetSoundHeader (Handle sndHandle);
  25. static pascal void SoundCallBack (SndChannelPtr chan, SndCommand cmd);
  26. SndChannelPtr InitChannel (long chanMode, SndCallBackUPP callBackProc);
  27. void DisposeChannel (SndChannelPtr chan);
  28. void DisposeLoopingChannel (void);
  29. static pascal void loopingCallBack (SndChannelPtr chan, SndCommand cmd);
  30.  
  31. void SetChanVol (short chanNum, short balance) {
  32. SndCommand    sc;
  33. long        rightvol;    // FVM 27/4/97
  34. long        leftvol;
  35. long        resultvol;
  36.  
  37.     if (sndChan[chanNum] != nil) {
  38.         if (balance < -128) balance = -128;
  39.         if (balance > 128) balance = 128;
  40.         
  41.         rightvol = 128 + balance;
  42.         leftvol = 128 - balance;
  43.         resultvol = (rightvol << 16) | leftvol;
  44.         
  45.         sc.cmd = volumeCmd;
  46.         sc.param1 = 0;
  47.         sc.param2 = resultvol;        // FVM 27/4/97
  48.         SndDoImmediate(sndChan[chanNum], &sc);
  49.     }
  50. }
  51.  
  52. void SetChanVolLR (short chanNum, short left, short right) {
  53. SndChannelPtr    chan;
  54. SndCommand        sc;
  55. long            vol;
  56.     
  57.     if (chanNum == kLoopingChan) chan = loopingSndChan;
  58.     else chan = sndChan[chanNum];
  59.     
  60.     if (chan != nil) {
  61.         if (left < -128) left = -128;
  62.         if (left > 128) left = 128;
  63.         if (right < -128) right = -128;
  64.         if (right > 128) right = 128;
  65.         vol = (right << 16L | left);
  66.         sc.cmd = volumeCmd;
  67.         sc.param1 = 0;
  68.         sc.param2 = vol;
  69.         SndDoImmediate(chan, &sc);
  70.     }
  71. }
  72.  
  73. void BalanceSndChannels (void) {
  74. short    x;
  75.  
  76.     for (x = 0; x < numChannels; x++) 
  77.         if (sndChanActive[x] == false) SetChanVol(x, kBalanced);
  78. }
  79.  
  80. short FindFreeChannel (void) {
  81. short    x;
  82.  
  83.     for (x = 0; x < numChannels; x++) 
  84.         if (sndChanActive[x] == false) return(x);
  85.     return(kNoFreeChannels);
  86. }
  87.  
  88. SndChannelPtr InitSoundChanPtr (long init) {
  89. SndChannelPtr    tempChan = nil;
  90.  
  91.     tempChan = InitChannel(init, nil);    
  92.     return(tempChan);
  93. }
  94.  
  95. short InitSoundChan (long init) {
  96. short    chanNum = ++numChannels;
  97.  
  98.     sndChan[chanNum] = InitChannel(init, soundCallBackUPP);
  99.     if (sndChan[chanNum] != nil) {
  100.         sndChanActive[chanNum] = false;
  101.         numChannels++;
  102.         return(chanNum);
  103.     }
  104.     
  105.     return(mFulErr);
  106. }
  107.  
  108. void DisposeSoundChan (short chanNum) {
  109.     if (sndChan[chanNum] != nil) {
  110.         DisposeChannel(sndChan[chanNum]);
  111.         sndChanActive[chanNum] = false;
  112.         numChannels--;
  113.     }
  114. }
  115.  
  116. void InitSoundUtils (short num) {
  117. short    x, y = 0, maxChannels;
  118.  
  119.     numChannels = 0;
  120.     maxChannels = num;
  121.  
  122.     soundCallBackUPP = NewSndCallBackProc(SoundCallBack);
  123.     
  124.     if (maxChannels != kNone) {
  125.         for (x = 0; x <= maxChannels; x++) {
  126.             sndChan[y] = InitChannel(initStereo, soundCallBackUPP);
  127.             if (sndChan[y] != nil) {
  128.                 sndChanActive[y] = false;
  129.                 numChannels++;
  130.                 y++;
  131.             } else y--;
  132.         }
  133.     }
  134. }
  135.  
  136. void DisposeSoundUtils (void) {
  137. short    x;
  138.  
  139.     for (x = 0; x < numChannels; x++) DisposeChannel(sndChan[x]);
  140.     DisposeRoutineDescriptor(soundCallBackUPP);
  141. }
  142.  
  143. static SoundHeaderPtr GetSoundHeader (Handle sndHandle) {
  144. long    offset;
  145.  
  146.     if (GetSoundHeaderOffset((SndListHandle)sndHandle, &offset) != noErr) return nil;
  147.     else return ((SoundHeaderPtr)((Ptr)(*sndHandle) + offset));
  148. }
  149.  
  150. static pascal void SoundCallBack (SndChannelPtr chan, SndCommand cmd) {
  151.     sndChanActive[chan->userInfo] = false;
  152. }
  153.  
  154. SndChannelPtr InitChannel (long chanMode, SndCallBackUPP callBackProc) {
  155. SndChannelPtr    chan = nil;
  156. long            init = chanMode;
  157.  
  158.     if (init != (initChanLeft|initChanRight|initNoInterp|initNoDrop|initMono|initStereo))
  159.         init = initMono + initNoInterp;
  160.     if ((SndNewChannel(&chan, sampledSynth, init, callBackProc) != noErr) || (MemError() != noErr) || (chan == nil)) 
  161.         DisposePtr((Ptr)chan);
  162.     return(chan);
  163. }
  164.  
  165. void DisposeChannel (SndChannelPtr chan) {
  166. SndCommand sc;
  167.  
  168.     if (chan != nil) {
  169.         sc.cmd = flushCmd;
  170.         sc.param1 = 0;
  171.         sc.param2 = 0;
  172.         SndDoImmediate(chan, &sc);
  173.         
  174.         sc.cmd = quietCmd;
  175.         sc.param1 = 0;
  176.         sc.param2 = 0;
  177.         SndDoImmediate(chan, &sc);
  178.         
  179.         SndDisposeChannel(chan, false);
  180.         DisposePtr((Ptr)chan);
  181.     }
  182. }
  183.  
  184. void SilenceChannel (short chanNum) {
  185. SndCommand sc;
  186.  
  187.     if (sndChan[chanNum] != nil) {
  188.         sc.cmd = flushCmd;
  189.         sc.param1 = 0;
  190.         sc.param2 = 0;
  191.         SndDoImmediate(sndChan[chanNum], &sc);
  192.         sc.cmd = quietCmd;
  193.         sc.param1 = 0;
  194.         sc.param2 = 0;
  195.         SndDoImmediate(sndChan[chanNum], &sc);
  196.         
  197.         sndChanActive[chanNum] = false;
  198.     }
  199. }
  200.  
  201. void SilenceChanPtr (SndChannelPtr chan) {
  202. SndCommand sc;
  203.  
  204.     if (chan != nil) {
  205.         sc.cmd = flushCmd;
  206.         sc.param1 = 0;
  207.         sc.param2 = 0;
  208.         SndDoImmediate(chan, &sc);
  209.         
  210.         sc.cmd = quietCmd;
  211.         sc.param1 = 0;
  212.         sc.param2 = 0;
  213.         SndDoImmediate(chan, &sc);
  214.     }
  215. }
  216.  
  217. void PlaySoundChanPtr (SndChannelPtr chan, Handle snd) {
  218. SndCommand     sc;
  219.  
  220.     if ((chan != nil) && (snd != nil)) {
  221.         sc.cmd = bufferCmd;
  222.         sc.param1 = 0;
  223.         sc.param2 = (long)GetSoundHeader(snd);
  224.         SndDoImmediate(chan, &sc);
  225.     }
  226. }
  227.  
  228. void PlaySndVol (Handle snd, short balance) {
  229. short    chanNum;
  230.     chanNum = FindFreeChannel();
  231.     SetChanVol(chanNum, balance);    // I put this BEFORE the PlaySoundChan() now instead..
  232.     PlaySoundChan(chanNum, snd);    // pretty stupid to change the volume after the sound has
  233. }                                    // already started :)    8/3/97
  234.  
  235. void PlaySnd (Handle snd) {
  236.     PlaySoundChan(FindFreeChannel(), snd);
  237. }
  238.  
  239. void PlaySoundChan (short chanNum, Handle snd) {
  240. SndCommand     sc;
  241.  
  242.     if ((sndChan[chanNum] != nil) && (snd != nil)) {
  243.         sc.cmd = bufferCmd;
  244.         sc.param1 = 0;
  245.         sc.param2 = (long)GetSoundHeader(snd);
  246.         SndDoImmediate(sndChan[chanNum], &sc);
  247.         
  248.         sndChanActive[chanNum] = true;
  249.         sndChan[chanNum]->userInfo = chanNum;
  250.         
  251.         sc.cmd = callBackCmd;
  252.         sc.param1 = 0;
  253.         sc.param2 = 0;
  254.         SndDoCommand(sndChan[chanNum], &sc, true);
  255.     }
  256. }
  257.  
  258. Boolean SndChanPtrBusy (SndChannelPtr chan) {
  259. SCStatus    scs;
  260.  
  261.     SndChannelStatus(chan, sizeof(SCStatus), &scs);
  262.     return(scs.scChannelBusy);
  263. }
  264.  
  265. void InitLoopingSounds (void) {
  266.     loopingCallBackUPP = NewSndCallBackProc(loopingCallBack);
  267.     loopingSndChan = InitChannel(initStereo, loopingCallBackUPP);
  268. }
  269.  
  270. void DisposeLoopingSounds (void) {
  271.     DisposeLoopingChannel();
  272.     DisposeRoutineDescriptor(loopingCallBackUPP);
  273. }
  274.  
  275. void PlayLoopingSound (Handle snd) {
  276. SndCommand    sc;
  277.  
  278.     if ((loopingSndChan != nil) && (snd != nil)) {
  279.         loopingSndChan->userInfo = (long)GetSoundHeader(snd);
  280.         
  281.         sc.cmd = callBackCmd;
  282.         sc.param1 = 0;
  283.         sc.param2 = 0;
  284.         SndDoCommand(loopingSndChan, &sc, false);
  285.     }
  286. }
  287.  
  288. void SilenceLoopingChannel (void) {
  289. SndCommand sc;
  290.  
  291.     if (loopingSndChan != nil) {
  292.         sc.cmd = flushCmd;
  293.         sc.param1 = 0;
  294.         sc.param2 = 0;
  295.         SndDoImmediate(loopingSndChan, &sc);
  296.         
  297.         sc.cmd = quietCmd;
  298.         sc.param1 = 0;
  299.         sc.param2 = 0;
  300.         SndDoImmediate(loopingSndChan, &sc);
  301.         
  302.         loopingActive = false;
  303.     }
  304. }
  305.  
  306. void DisposeLoopingChannel (void) {
  307.     if (loopingSndChan != nil) {
  308.         SilenceLoopingChannel();
  309.         
  310.         SndDisposeChannel(loopingSndChan, false);
  311.         DisposePtr((Ptr)loopingSndChan);
  312.     }
  313. }
  314.  
  315. static pascal void loopingCallBack (SndChannelPtr chan, SndCommand cmd) {
  316. SndCommand    sc;
  317.     sc.cmd = bufferCmd;
  318.     sc.param1 = 0;
  319.     sc.param2 = chan->userInfo;
  320.     SndDoImmediate(chan, &sc);
  321.         
  322.     sc.cmd = callBackCmd;
  323.     sc.param1 = 0;
  324.     sc.param2 = 0;
  325.     SndDoCommand(chan, &sc, true);
  326. }